package com.example.blog.aop;

import com.example.blog.controller.BaseController;
import com.example.blog.domain.Permission;
import com.example.blog.domain.Users;
import com.example.blog.exception.BusinessException;
import com.example.blog.mapper.UsersMapper;
import com.example.blog.note.Permissions;
import com.example.blog.utils.JwtUtils;
import com.example.blog.utils.RedisStorage;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.List;;
import java.util.stream.Collectors;

import static com.example.blog.domain.Response.ERROR_Permissions;

@Aspect  //说明该对象是一个切面
@Component
@Slf4j
@Order(1)
public class PermissionVerification extends BaseController {
    private final RedisStorage redisStorage;
    private final UsersMapper usersMapper;

    @Autowired
    public PermissionVerification(RedisStorage redisStorage, UsersMapper usersMapper) {
        this.redisStorage = redisStorage;
        this.usersMapper = usersMapper;
    }


    @Around("@annotation(permissions)")
    public Object permission(ProceedingJoinPoint joinPoint, Permissions permissions) throws Throwable {

        HttpServletRequest request = getHttpInfo();
        Claims claims = JwtUtils.checkToken(request.getHeader("token"));
        boolean result = claims != null ? redisStorage.checkPermission(Long.parseLong(String.valueOf(claims.get("uid"))), permissions.value()) : false;
        boolean permission_;
        if (!result) {
            Object[] objects = joinPoint.getArgs();
            String name = (objects[0] instanceof Users) ? ((Users) objects[0]).getUsername() : (String) claims.get("username");
            List<Permission>  list = usersMapper.findPermissionByAccount(name);
            permission_ = list.stream().anyMatch(s -> s.getUrl().equals(permissions.value()));
            if (permission_) {
                if(!(objects[0] instanceof Users)){
                    List<String> list_p = list.stream().map(Permission::getUrl).collect(Collectors.toList());
                    redisStorage.setPermission(list_p, Long.parseLong(String.valueOf(claims.get("uid"))));
                }
            }else {
                 throw new BusinessException(ERROR_Permissions, "权限校验失败");
            }
        }
        // 执行原本的方法，并获取原本方法的返回值
        return joinPoint.proceed();
    }

}
